package com.ruoyi.mdm.service.impl;

import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.mdm.domain.SkuInfoEntity;
import com.ruoyi.mdm.repository.SkuInfoRepository;
import com.ruoyi.mdm.service.ISkuInfoService;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.script.Script;
import org.elasticsearch.script.ScriptType;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.sort.ScriptSortBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.client.erhlc.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.client.erhlc.NativeSearchQuery;
import org.springframework.data.elasticsearch.client.erhlc.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.Query;
import org.springframework.stereotype.Service;

import jakarta.annotation.Resource;
import java.util.*;

@Service
public class SkuInfoServiceImpl implements ISkuInfoService {

    @Resource
    private ElasticsearchRestTemplate elasticsearchRestTemplate;

    @Resource
    private SkuInfoRepository skuInfoRepository;


    @Override
    public SearchHits<SkuInfoEntity> searchSkuInfo(SkuInfoEntity skuInfoEntity) {

        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();

        // 服务渠道（精确）
        if (StringUtils.isNotEmpty(skuInfoEntity.getChannelCode())) {
            boolQueryBuilder.must(QueryBuilders.termQuery("channel_code", skuInfoEntity.getChannelCode()));
        }

        // 品牌编码 多个时候 或者
        if (StringUtils.isNotEmpty(skuInfoEntity.getOwnerId())) {

            List<String> ownerIdList = Arrays.asList(skuInfoEntity.getOwnerId().split(","));

            BoolQueryBuilder boolOwnerBuilder = QueryBuilders.boolQuery();
            for (String ownerId : ownerIdList) {
                boolOwnerBuilder.should(QueryBuilders.termQuery("owner_id", ownerId));
            }
            boolOwnerBuilder.minimumShouldMatch(1);

            boolQueryBuilder.must(boolOwnerBuilder);
        }

        // 销售渠道（模糊）
        if (StringUtils.isNotEmpty(skuInfoEntity.getSkuSalesChannel())) {
            boolQueryBuilder.must(QueryBuilders.matchPhrasePrefixQuery("sku_sales_channel", skuInfoEntity.getSkuSalesChannel()));
        }

        // 关键字（模糊）
        if (StringUtils.isNotEmpty(skuInfoEntity.getKeyword())) {
//            boolQueryBuilder.must(QueryBuilders.matchQuery("keyword", skuInfoEntity.getKeyword()));
            boolQueryBuilder.must(QueryBuilders.matchPhrasePrefixQuery("keyword", skuInfoEntity.getKeyword()));
            // 暂不处理 品牌、SKU中文名称、SKU英文名称、SKU简称、SKUM中文名称、SKUM英文名称、SKUM简称、SPU中文名称、SPU英文名称、SPU简称、昵称
//            boolQueryBuilder.must(QueryBuilders.multiMatchQuery(skuInfoEntity.getKeyword(),
//                    "owner_name", "goods_name", "goods_name_en", "goods_short_name",
//                    "skumName", "skum_name_en", "skum_short_name", "spu_name", "spu_name_en", "spu_short_name", "spu_nick_name"));
        }

        // 产品编码（精确）
        if (StringUtils.isNotEmpty(skuInfoEntity.getGoodsCode())) {
            boolQueryBuilder.must(QueryBuilders.termQuery("goods_code", skuInfoEntity.getGoodsCode()));
        }

        // 产品条码（精确）
        if (StringUtils.isNotEmpty(skuInfoEntity.getBarCode())) {
            boolQueryBuilder.must(QueryBuilders.termQuery("bar_code", skuInfoEntity.getBarCode()));
        }

        // 价格（精确）
        if (skuInfoEntity.getSalePrice() != null) {
            boolQueryBuilder.must(QueryBuilders.termQuery("sale_price", skuInfoEntity.getSalePrice()));
        }

        // 条件+排序+分页
        NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();

        // 条件
        nativeSearchQueryBuilder.withQuery(boolQueryBuilder);

        // 模糊检索 并且有服务渠道
        if (StringUtils.isNotEmpty(skuInfoEntity.getChannelCode()) &&
            (StringUtils.isNotEmpty(skuInfoEntity.getKeyword()) || StringUtils.isNotEmpty(skuInfoEntity.getSkuSalesChannel()))
         ) {
            // 定义脚本 自定义排序
            Script script = new Script(
                    ScriptType.INLINE,
                    "painless",
                    "_score * 0.5 + doc['total_score'].value * 0.5",
                    Collections.emptyMap()
            );
            // 创建排序构建器
            ScriptSortBuilder sortBuilder = new ScriptSortBuilder(script, ScriptSortBuilder.ScriptSortType.NUMBER);
            sortBuilder.order(SortOrder.DESC);
            nativeSearchQueryBuilder.withSort(sortBuilder);
        }

        // 模糊检索条件存在时  以外情况用 更新时间倒序
        if (StringUtils.isNotEmpty(skuInfoEntity.getKeyword())
            || StringUtils.isNotEmpty(skuInfoEntity.getSkuSalesChannel())) {

            // 命中得分排序
            nativeSearchQueryBuilder.withSort(SortBuilders.scoreSort().order(SortOrder.DESC));
        }

        // 排序 服务渠道不为空时
        if (StringUtils.isNotEmpty(skuInfoEntity.getChannelCode())) {
            nativeSearchQueryBuilder.withSort(SortBuilders.fieldSort("total_score").order(SortOrder.DESC));
        }

        // 销售开始日排序
        nativeSearchQueryBuilder.withSort(SortBuilders.fieldSort("sale_begin_date.keyword").order(SortOrder.DESC));

        // 分页
        nativeSearchQueryBuilder.withPageable(PageRequest.of(skuInfoEntity.getPage(), skuInfoEntity.getSize()));

        // 去重
        nativeSearchQueryBuilder.withCollapseField("sku_id");

//        // 求去重后总数
//        nativeSearchQueryBuilder.addAggregation(AggregationBuilders.cardinality("total_size")
//                .field("sku_id").precisionThreshold(4000));
        nativeSearchQueryBuilder.addAggregation(AggregationBuilders.terms("distinct_values").field("sku_id").size(20000));

        NativeSearchQuery nativeSearchQuery = nativeSearchQueryBuilder.build();

        // 手动设置 track_total_hits
        nativeSearchQuery.setTrackTotalHits(true);

        String queryDsl = nativeSearchQuery.getQuery().toString();
        System.out.println("Generated Query DSL: " + queryDsl);

        return elasticsearchRestTemplate.search(nativeSearchQuery, SkuInfoEntity.class);
    }

    @Override
    public SkuInfoEntity findById(String id) {
        Optional<SkuInfoEntity> optionalSkuInfoEntity = skuInfoRepository.findById(id);
        return optionalSkuInfoEntity.get();
    }

    @Override
    public int add(SkuInfoEntity skuInfoEntity) {
        skuInfoRepository.save(skuInfoEntity);
        return 1;
    }

    @Override
    public int addAll(List<SkuInfoEntity> skuInfoEntityList) {
        skuInfoRepository.saveAll(skuInfoEntityList);
        return 1;
    }

    @Override
    public int delete(String id) {
        skuInfoRepository.deleteById(id);
        return 1;
    }

    @Override
    public int deleteAll() {
        skuInfoRepository.deleteAll();
        return 1;

    }

}
